﻿using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.Win32;
using SPDocumentor.SPModel;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Management;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using DocumentGeneratorPlugins;
using System.Web;
using SPDocumentor.SPModel.SPServiceApplications;
using DocumentorLog;
using SharePointDocumentor.SPModel;
using Microsoft.SharePoint.Workflow;

namespace SPDocumentor.SPHelpers
{
    public delegate void FarmEventHandler(object sender, SharePointDocumentor.SPModel.FarmEventArgs fea);


    public class FarmLoader
    {
        private static FarmLoader _current;
        private static Hashtable _products;
        private static List<Server> lstServ;
        private static List<WebApplication> _lstWebApps;
        private const String SharePointProductsRegistryPath = @"SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\15.0\WSS\InstalledProducts\";
        private static Logger Log = Logger.Current;
        public static event FarmEventHandler FarmEvent;

        public static FarmLoader Current
        {
            get
            {
                if (_current == null)
                    _current = new FarmLoader();
                return _current;
            }
        }

        private static void OnFarmEvent(String Message)
        {
            if (FarmEvent != null)
            {
                SharePointDocumentor.SPModel.FarmEventArgs fea = new SharePointDocumentor.SPModel.FarmEventArgs();
                fea.Message = Message;
                FarmEvent(null, fea);
            }
        }
        private static Hashtable SharePointProducts
        {
            get
            {
                if (_products == null)
                {
                    Log.Info("Get product ID");
                    OnFarmEvent("Get Product ID");
                    _products = new Hashtable();
                    _products.Add("35466B1A-B17B-4DFB-A703-F74E2A1F5F5E", "Project Server 2013");
                    _products.Add("BC7BAF08-4D97-462C-8411-341052402E71", "Project Server 2013 Preview");
                    _products.Add("C5D855EE-F32B-4A1C-97A8-F0A28CE02F9C", "SharePoint Server 2013");
                    _products.Add("CBF97833-C73A-4BAF-9ED3-D47B3CFF51BE", "SharePoint Server 2013 Preview");
                    _products.Add("B7D84C2B-0754-49E4-B7BE-7EE321DCE0A9", "SharePoint Server 2013 Enterprise");
                    _products.Add("298A586A-E3C1-42F0-AFE0-4BCFDC2E7CD0", "SharePoint Server 2013 Enterprise Preview");
                    _products.Add("D6B57A0D-AE69-4A3E-B031-1F993EE52EDC", "Microsoft Office Online");
                    _products.Add("9FF54EBC-8C12-47D7-854F-3865D4BE8118", "SharePoint Foundation 2013");
                }
                return _products;
            }
        }

        public Farm LoadFarm()
        {
            Log.Info("Load Farm");
            OnFarmEvent("Load Farm");
            Farm frm = new Farm();
            try
            {

                SPFarm LocalFarm = SPFarm.Local;
                frm.SharePointVersion = LocalFarm.BuildVersion.ToString();

                frm.ServiceAccount = LocalFarm.DefaultServiceAccount.SecurityIdentifier.Value;
                frm.DiskSizeBackupRequired = LocalFarm.DiskSizeRequired;
                frm.DisplayName = LocalFarm.DisplayName;
                frm.Features = FillFarmFeatures(LocalFarm);
                frm.AlternateUrlCollection = FillAlternateUrlCollections(LocalFarm.AlternateUrlCollections);
                frm.DaysBeforePasswordExpirationToSendEmail = LocalFarm.DaysBeforePasswordExpirationToSendEmail;
                frm.DefaultServiceAccount = FillServiceAccount(LocalFarm.DefaultServiceAccount);
                frm.PasswordChangeEmailAddress = LocalFarm.PasswordChangeEmailAddress;
                frm.PasswordChangeGuardTime = LocalFarm.PasswordChangeGuardTime;
                frm.PasswordChangeMaximumTries = LocalFarm.PasswordChangeMaximumTries;
                frm.Solutions = FillSolution(LocalFarm.Solutions);
                frm.TimerService = FillTimerServices(LocalFarm.TimerService);
                frm.FeatureDefinitions = FillFeatureDefinitions(LocalFarm.FeatureDefinitions);
                frm.ServiceApplicationProxyGroups = FillServiceApplicationProxyGroups(LocalFarm.ServiceApplicationProxyGroups);
                frm.SharePointEdition = GetSharePointEdition();
                frm.SharePointConfigDB = GetConfigDbConnectionString(LocalFarm);
                frm.Servers = FillServers(LocalFarm.Servers);
                frm.WebApps = FillWebApps(LocalFarm);
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement de la ferme", ex);
            }
            return frm;
        }

        private TimerService FillTimerServices(SPTimerService sPTimerService)
        {
            TimerService ts = new TimerService();
            try
            {
                ts.DisplayName = sPTimerService.DisplayName;
                ts.AccountName = sPTimerService.ProcessIdentity.ManagedAccount.Username;
                ts.JobDefinitions = FillJobDefinitions(sPTimerService.JobDefinitions);
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement des timer service", ex);
            }
            return ts;
        }

        private JobDefinition[] FillJobDefinitions(SPJobDefinitionCollection SPJobDefinitions)
        {
            List<JobDefinition> lstJpobDef = new List<JobDefinition>();
            try
            {
                OnFarmEvent("Load Job Definition");
                foreach (SPJobDefinition spjd in SPJobDefinitions)
                {
                    
                    JobDefinition jd = new JobDefinition();
                    jd.Description = spjd.Description;
                    jd.DisplayName = spjd.DisplayName;
                    jd.IsDisabled = spjd.IsDisabled;
                    jd.LastRunTime = spjd.LastRunTime;
                    if (spjd.Server != null)
                        jd.ServerName = spjd.Server.Name;
                    if (spjd.Service != null)
                        jd.ServiceName = spjd.Service.DisplayName;
                    if (spjd.WebApplication != null)
                        jd.WebAppName = spjd.WebApplication.DisplayName;
                    jd.JobHistories = FillJobHistory(spjd.HistoryEntries);
                    lstJpobDef.Add(jd);
                }
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement des JobDefinition", ex);
            }
            return lstJpobDef.ToArray();
        }

        private JobHistory[] FillJobHistory(IEnumerable<SPJobHistory> JobHistories)
        {
            
            List<JobHistory> lstJH = new List<JobHistory>();
            try
            {
                var topJobHistories = JobHistories.Take(10);
                foreach (SPJobHistory spjh in topJobHistories)
                {
                    JobHistory jh = new JobHistory();
                    jh.DatabaseName = spjh.DatabaseName;
                    jh.EndTime = spjh.EndTime;
                    jh.ErrorMessage = spjh.ErrorMessage;
                    jh.JobDefinitionTitle = spjh.JobDefinitionTitle;
                    jh.ServerName = spjh.ServerName;
                    jh.StartTime = spjh.StartTime;
                    jh.Status = spjh.Status.ToString();
                    jh.WebApplicationName = spjh.WebApplicationName;
                    lstJH.Add(jh);
                }
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement des JobHistory", ex);
            }
            return lstJH.ToArray();
        }

        private string FillServiceAccount(SPProcessAccount sPProcessAccount)
        {
            OnFarmEvent("Fill Service Account");
            string account = "";
            try
            {
                account = new System.Security.Principal.SecurityIdentifier(sPProcessAccount.SecurityIdentifier.Value).Translate(typeof(System.Security.Principal.NTAccount)).ToString();
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement des Service Account", ex);
            }
            return account;
        }

        private Solutions[] FillSolution(SPSolutionCollection sPSolutionCollection)
        {

            List<Solutions> lstSolution = new List<Solutions>();
            try
            {
                OnFarmEvent("Fill Solution");
                foreach (SPSolution solution in sPSolutionCollection)
                {
                    
                    Solutions sol = new Solutions();
                    sol.ContainsCasPolicy = solution.ContainsCasPolicy;
                    sol.ContainsGlobalAssembly = solution.ContainsGlobalAssembly;
                    sol.ContainsWebApplicationResource = solution.ContainsWebApplicationResource;
                    sol.Deployed = solution.Deployed;
                    sol.Servers = FillServers(solution.DeployedServers);
                    if (solution.ContainsWebApplicationResource)
                        sol.DeployedWebApplications = FillWebApps(solution.DeployedWebApplications.ToList());
                    sol.DeploymentState = solution.DeploymentState.ToString();
                    sol.DisplayName = solution.DisplayName;
                    sol.IsWebPartPackage = solution.IsWebPartPackage;
                    sol.JobExists = solution.JobExists;
                    if (solution.JobExists)
                        sol.JobStatus = solution.JobStatus.ToString();
                    sol.SolutionFile = solution.SolutionFile.DisplayName;
                    sol.SolutionId = solution.SolutionId;
                    lstSolution.Add(sol);
                }
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement des Solutions", ex);
            }
            return lstSolution.ToArray();
        }

        private Server[] FillServers(System.Collections.ObjectModel.Collection<SPServer> ssc)
        {
            if (lstServ != null)
                return lstServ.ToArray();
            lstServ = new List<Server>();
            try
            {
                OnFarmEvent("Fill Server");
                foreach (SPServer s in ssc)
                {
                    
                    Server srv = new Server();
                    srv.ServerName = s.DisplayName;
                    srv.Role = s.Role.ToString();
                    srv.OperatingSystem = GetOS(s.Address);
                    srv.Memory = GetMemory(s.Address);
                    srv.Drives = GetSpace(s.Address);
                    srv.Patches = getPatches(s.Address);
                    srv.Services = FillServices(s.ServiceInstances);
                    lstServ.Add(srv);
                }
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement des Serveurs", ex);
            }
            return lstServ.ToArray();
        }

        private AlternateUrl[] FillAlternateUrlCollections(SPAlternateUrlCollectionManager sPAlternateUrlCollectionManager)
        {
            List<AlternateUrl> lstAltUrl = new List<AlternateUrl>();
            try
            {
                OnFarmEvent("Fill AAM");
                foreach (SPAlternateUrlCollection urls in sPAlternateUrlCollectionManager)
                {
                    
                    AlternateUrl au = new AlternateUrl();
                    au.DisplayName = urls.DisplayName;
                    foreach (SPAlternateUrl url in urls)
                    {
                        switch (url.UrlZone)
                        {
                            case SPUrlZone.Custom:
                                au.CustomZoneURL = url.Uri.AbsoluteUri;
                                break;
                            case SPUrlZone.Default:
                                au.DefaultZoneURL = url.Uri.AbsoluteUri;
                                break;
                            case SPUrlZone.Extranet:
                                au.ExtranetZoneURL = url.Uri.AbsoluteUri;
                                break;
                            case SPUrlZone.Internet:
                                au.InternetZoneURL = url.Uri.AbsoluteUri;
                                break;
                            case SPUrlZone.Intranet:
                                au.IntranetZoneURL = url.Uri.AbsoluteUri;
                                break;

                        }
                        lstAltUrl.Add(au);
                    }

                }
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement des AAM", ex);
            }
            return lstAltUrl.ToArray();
        }

        private Feature[] FillFarmFeatures(SPFarm LocalFarm)
        {
            OnFarmEvent("Fill Farm Feature");

            List<WebApplication> lstWebApps = new List<WebApplication>();
            SPWebService wsc = new SPWebService("AdministrationService", LocalFarm);
            return FillFeature(wsc.Features);

        }

        private ApplicationProxyGroup[] FillServiceApplicationProxyGroups(SPServiceApplicationProxyGroupCollection SPServiceApplicationProxyGroups)
        {
            OnFarmEvent("Fill Application Proxy group");

            List<ApplicationProxyGroup> lstReturn = new List<ApplicationProxyGroup>();
            try
            {
                foreach (SPServiceApplicationProxyGroup group in SPServiceApplicationProxyGroups)
                {
                    lstReturn.Add(FillServiceApplicationProxyGroup(group));
                }
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement des Proxy groups", ex);
            }
            return lstReturn.ToArray();
        }

        private ApplicationProxyGroup FillServiceApplicationProxyGroup(SPServiceApplicationProxyGroup group)
        {

            ApplicationProxyGroup apg = new ApplicationProxyGroup();
            try
            {
                apg.DisplayName = string.IsNullOrEmpty(group.DisplayName) ? "Default" : group.DisplayName;
                apg.Name = string.IsNullOrEmpty(group.Name) ? "Default" : group.Name;
                apg.Proxies = FillServiceApplicationProxies(group.Proxies);
                apg.ID = group.Id;
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement des Proxy group", ex);
            }
            return apg;
        }

        private ServiceApplication[] FillServiceApplication(SPServiceApplicationCollection SPServiceApplications)
        {
            OnFarmEvent("Fill Service Application");

            List<ServiceApplication> lstSA = new List<ServiceApplication>();
            try
            {
                foreach (SPServiceApplication application in SPServiceApplications)
                {
                    lstSA.Add(ServiceApplicationFactory.GetServiceApplication(application));
                }
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement des Service Application", ex);
            }
            return lstSA.ToArray();
        }

        private ApplicationProxy[] FillServiceApplicationProxies(IEnumerable<SPServiceApplicationProxy> SPServiceApplicationProxies)
        {
            OnFarmEvent("Fill Application Proxy");

            List<ApplicationProxy> lstReturn = new List<ApplicationProxy>();
            try
            {
                foreach (SPServiceApplicationProxy proxy in SPServiceApplicationProxies)
                {

                    ApplicationProxy ap = new ApplicationProxy();
                    ap.DisplayName = proxy.DisplayName;
                    ap.Name = proxy.TypeName;
                    ap.ID = proxy.Id;
                    lstReturn.Add(ap);
                }
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement des Service Application Proxies", ex);
            }
            return lstReturn.ToArray();
        }

        private FeatureDefinition[] FillFeatureDefinitions(SPFeatureDefinitionCollection SPFeatureDefinitions)
        {
            //OnFarmEvent("Fill Feature Definition");

            List<FeatureDefinition> lstReturn = new List<FeatureDefinition>();
            try
            {
                foreach (SPFeatureDefinition fd in SPFeatureDefinitions)
                {
                    FeatureDefinition def = FillFeatureDefinition(fd);
                    lstReturn.Add(def);
                }
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement des Features Definitions", ex);
            }
            return lstReturn.ToArray();
        }

        private static FeatureDefinition FillFeatureDefinition(SPFeatureDefinition fd)
        {
            FeatureDefinition def = new FeatureDefinition();
            try
            {
                def.FeatureID = fd.Id;
                def.DisplayName = fd.DisplayName;
                def.Hidden = fd.Hidden;
                def.Name = fd.Name;
                def.ReceiverAssembly = fd.ReceiverAssembly;
                def.ReceiverClass = fd.ReceiverClass;
                def.RootDirectory = fd.RootDirectory;
                def.Scope = fd.Scope.ToString();
                def.Version = fd.Version.ToString();
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement des Features Definition", ex);
            }
            return def;
        }

        private WebApplication[] FillWebApps(SPFarm LocalFarm)
        {
            OnFarmEvent("Fill Web Applications");

            List<WebApplication> lstWebApps = new List<WebApplication>();
            try
            {
                SPWebServiceCollection wsc = new SPWebServiceCollection(LocalFarm);
                foreach (SPWebService ws in wsc)
                {
                    List<SPWebApplication> lstSPWebApp = ws.WebApplications.ToList();
                    lstWebApps.AddRange(FillWebApps(lstSPWebApp));

                }
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement des Web Apps", ex);
            }
            return lstWebApps.ToArray();
        }

        private WebApplication[] FillWebApps(List<SPWebApplication> lstSPWebApp)
        {

            List<WebApplication> lstWebApps = new List<WebApplication>();
            try
            {
                OnFarmEvent("Fill Web Application");
                foreach (SPWebApplication swa in lstSPWebApp)
                {
                    WebApplication wa = new WebApplication();
                    //if (swa.Name == "MySite.Contoso.com")
                    //    continue;
                    if (_lstWebApps == null)
                        _lstWebApps = new List<WebApplication>();

                    var webapp = (from w in _lstWebApps where w.Name == swa.Name select w);
                    if(webapp.Count()!=0)
                    {
                        lstWebApps.Add(webapp.FirstOrDefault());
                        continue;
                    }

                    wa.AlternateUrls = FillAlternateUrl(swa.AlternateUrls);
                    wa.BlockedFiles = swa.BlockedFileExtensions;
                    wa.ClaimsEnabled = swa.UseClaimsAuthentication;
                    wa.DisplayName = swa.DisplayName;
                    wa.ServiceApplicationProxyGroup = FillServiceApplicationProxyGroup(swa.ServiceApplicationProxyGroup);
                    wa.AlertsEnabled = swa.AlertsEnabled;
                    wa.AlertsLimited = swa.AlertsLimited;
                    wa.AlertsMaximum = swa.AlertsMaximum;
                    wa.AlertsMaximumQuerySet = swa.AlertsMaximumQuerySet;
                    wa.AllowAccessToWebPartCatalog = swa.AllowAccessToWebPartCatalog;
                    wa.AllowAnalyticsCookieForAnonymousUsers = swa.AllowAnalyticsCookieForAnonymousUsers;
                    wa.AllowContributorsToEditScriptableParts = swa.AllowContributorsToEditScriptableParts;
                    wa.AllowCreateDeclarativeWorkflow = swa.AllowCreateDeclarativeWorkflow;
                    wa.AllowDesigner = swa.AllowDesigner;
                    wa.AllowedInlineDownloadedMimeTypes = swa.AllowedInlineDownloadedMimeTypes.ToArray<string>();
                    wa.AllowHighCharacterListFolderNames = swa.AllowHighCharacterListFolderNames;
                    wa.AllowMasterPageEditing = swa.AllowMasterPageEditing;
                    wa.AllowOMCodeOverrideThrottleSettings = swa.AllowOMCodeOverrideThrottleSettings;
                    wa.AllowPartToPartCommunication = swa.AllowPartToPartCommunication;
                    wa.AllowRevertFromTemplate = swa.AllowRevertFromTemplate;
                    wa.AllowSaveDeclarativeWorkflowAsTemplate = swa.AllowSaveDeclarativeWorkflowAsTemplate;
                    wa.AllowSavePublishDeclarativeWorkflow = swa.AllowSavePublishDeclarativeWorkflow;
                    wa.AllowSelfServiceUpgradeEvaluation = swa.AllowSelfServiceUpgradeEvaluation;
                    wa.AllowSilverlightPrompt = swa.AllowSilverlightPrompt;
                    wa.AlwaysProcessDocuments = swa.AlwaysProcessDocuments;
                    ApplicationPool appPool = new ApplicationPool();
                    appPool.DisplayName = swa.ApplicationPool.DisplayName;
                    appPool.UserName = swa.ApplicationPool.Username;
                    appPool.Name = swa.ApplicationPool.DisplayName;
                    appPool.Password = GetApplicationPoolPassword(swa.ApplicationPool.Name);
                    wa.ApplicationPool = appPool;
                    wa.AutomaticallyDeleteUnusedSiteCollections = swa.AutomaticallyDeleteUnusedSiteCollections;
                    wa.BlockedFileExtensions = swa.BlockedFileExtensions.ToArray<string>();
                    wa.BrowserCEIPEnabled = swa.BrowserCEIPEnabled;
                    wa.CanRenameOnRestore = swa.CanRenameOnRestore;
                    wa.CanSelectForBackup = swa.CanSelectForBackup;
                    wa.CanSelectForRestore = swa.CanSelectForRestore;
                    wa.CanUpgrade = swa.CanUpgrade;
                    wa.CascadeDeleteMaximumItemLimit = swa.CascadeDeleteMaximumItemLimit;
                    wa.CascadeDeleteTimeoutMultiplier = swa.CascadeDeleteTimeoutMultiplier;
                    wa.CellStorageWebServiceEnabled = swa.CellStorageWebServiceEnabled;
                    wa.ChangeLogExpirationEnabled = swa.ChangeLogExpirationEnabled;
                    wa.ChangeLogRetentionPeriod = swa.ChangeLogRetentionPeriod;
                    CompatibilityRange cr = new CompatibilityRange();
                    cr.DefaultCompatibilityLevel = swa.CompatibilityRange.DefaultCompatibilityLevel;
                    cr.MaxCompatibilityLevel = swa.CompatibilityRange.MaxCompatibilityLevel;
                    cr.MinCompatibilityLevel = swa.CompatibilityRange.MinCompatibilityLevel;
                    cr.Singular = swa.CompatibilityRange.Singular;
                    wa.CompatibilityRange = cr;
                    wa.CrossDomainPhotosEnabled = swa.CrossDomainPhotosEnabled;
                    wa.CustomAppErrorLimit = swa.CustomAppErrorLimit;
                    wa.DailyStartUnthrottledPrivilegedOperationsHour = swa.DailyStartUnthrottledPrivilegedOperationsHour;
                    wa.DailyStartUnthrottledPrivilegedOperationsMinute = swa.DailyStartUnthrottledPrivilegedOperationsMinute;
                    wa.DailyUnthrottledPrivilegedOperationsDuration = swa.DailyUnthrottledPrivilegedOperationsDuration;
                    wa.DaysToShowNewIndicator = swa.DaysToShowNewIndicator;
                    wa.DefaultQuotaTemplate = swa.DefaultQuotaTemplate;
                    wa.DefaultServerComment = swa.DefaultServerComment;
                    wa.DefaultTimeZone = swa.DefaultTimeZone;
                    wa.DesignerDownloadUrl = swa.DesignerDownloadUrl;
                    wa.DisableCoauthoring = swa.DisableCoauthoring;
                    wa.DiskSizeRequired = swa.DiskSizeRequired;
                    wa.DocumentLibraryCalloutOfficeWebAppPreviewersDisabled = swa.DocumentLibraryCalloutOfficeWebAppPreviewersDisabled;
                    wa.EmailToNoPermissionWorkflowParticipantsEnabled = swa.EmailToNoPermissionWorkflowParticipantsEnabled;
                    if (swa.EnabledClaimProviders != null)
                        wa.EnabledClaimProviders = swa.EnabledClaimProviders.ToArray<string>();
                    wa.EventLogRetentionPeriod = swa.EventLogRetentionPeriod;
                    wa.ExternalWorkflowParticipantsEnabled = swa.ExternalWorkflowParticipantsEnabled;
                    //wa.Features = swa.Features;
                    wa.FileNotFoundPage = swa.FileNotFoundPage;
                    wa.ForceseekEnabled = swa.ForceseekEnabled;
                    //wa.HttpThrottleSettings = swa.HttpThrottleSettings;
                    wa.Id = swa.Id;
                    IisSettings iisSetting = new IisSettings();
                    foreach (var iis in swa.IisSettings)
                    {
                        switch (iis.Key)
                        {
                            case SPUrlZone.Custom:
                                iisSetting.CustomZone = FillIisSettings(iisSetting, iis);
                                break;
                            case SPUrlZone.Default:
                                iisSetting.Default = FillIisSettings(iisSetting, iis);
                                break;
                            case SPUrlZone.Extranet:
                                iisSetting.Extranet = FillIisSettings(iisSetting, iis);
                                break;
                            case SPUrlZone.Internet:
                                iisSetting.Internet = FillIisSettings(iisSetting, iis);
                                break;
                            case SPUrlZone.Intranet:
                                iisSetting.Intranet = FillIisSettings(iisSetting, iis);
                                break;

                        }
                    }
                    wa.IisSettings = iisSetting;
                    wa.IncomingEmailServerAddress = swa.IncomingEmailServerAddress;
                    wa.InheritDataRetrievalSettings = swa.InheritDataRetrievalSettings;
                    wa.IsAdministrationWebApplication = swa.IsAdministrationWebApplication;
                    if (swa.IsBackwardsCompatible == TriState.True)
                        wa.IsBackwardsCompatible = true;
                    else
                        wa.IsBackwardsCompatible = false;
                    wa.JobDefinitions = FillJobDefinitions(swa.JobDefinitions);
                    wa.JobHistoryEntries = FillJobHistory(swa.JobHistoryEntries);
                    wa.LookupDropDownUseStandardControl = swa.LookupDropDownUseStandardControl;
                    wa.MasterPageReferenceEnabled = swa.MasterPageReferenceEnabled;
                    wa.MaximumFileSize = swa.MaximumFileSize;
                    wa.MaximumFileSizePerExtension = new SerializableDictionary<string, int>(swa.MaximumFileSizePerExtension);
                    wa.MaxItemsPerThrottledOperation = swa.MaxItemsPerThrottledOperation;
                    wa.MaxItemsPerThrottledOperationOverride = swa.MaxItemsPerThrottledOperationOverride;
                    wa.MaxItemsPerThrottledOperationWarningLevel = swa.MaxItemsPerThrottledOperationWarningLevel;
                    wa.MaxQueryLookupFields = swa.MaxQueryLookupFields;
                    wa.MaxSizeForSelfServiceEvalSiteCreationMB = swa.MaxSizeForSelfServiceEvalSiteCreationMB;
                    wa.MaxUniquePermScopesPerList = swa.MaxUniquePermScopesPerList;
                    wa.MetaWeblogAuthenticationEnabled = swa.MetaWeblogAuthenticationEnabled;
                    wa.MetaWeblogEnabled = swa.MetaWeblogEnabled;
                    wa.MimeMappings = FillMimeMappings(swa.MimeMappings);
                    wa.Name = swa.Name;
                    //wa.OfficialFileHosts = swa.OfficialFileHosts;
                    wa.OfficialFileName = swa.OfficialFileName;
                    wa.OfficialFileUrl =swa.OfficialFileUrl==null?null: swa.OfficialFileUrl.AbsoluteUri;
                    wa.OutboundMailCodePage = swa.OutboundMailCodePage;
                    wa.OutboundMailReplyToAddress = swa.OutboundMailReplyToAddress;
                    wa.OutboundMailSenderAddress = swa.OutboundMailSenderAddress;
                    //wa.OutboundMailServiceInstance = swa.OutboundMailServiceInstance;
                    //wa.OutboundMmsServiceAccount = swa.OutboundMmsServiceAccount;
                    //wa.OutboundSmsServiceAccount = swa.OutboundSmsServiceAccount;
                    //wa.PeoplePickerSettings = swa.PeoplePickerSettings;
                    //wa.Policies = swa.Policies;
                    //wa.PolicyRoles = swa.PolicyRoles;
                    //wa.Prefixes = swa.Prefixes;
                    wa.PresenceEnabled = swa.PresenceEnabled;
                    wa.ReadOnlyMaintenanceLink = swa.ReadOnlyMaintenanceLink;
                    wa.RecycleBinCleanupEnabled = swa.RecycleBinCleanupEnabled;
                    wa.RecycleBinEnabled = swa.RecycleBinEnabled;
                    wa.RecycleBinRetentionPeriod = swa.RecycleBinRetentionPeriod;
                    wa.RenderingFromMetainfoEnabled = swa.RenderingFromMetainfoEnabled;
                    //wa.RequestManagementSettings = swa.RequestManagementSettings;
                    wa.RequireContactForSelfServiceSiteCreation = swa.RequireContactForSelfServiceSiteCreation;
                    wa.RequiredDesignerVersion = swa.RequiredDesignerVersion;
                    //wa.RightsMask = swa.RightsMask;
                    //wa.RunningJobs = swa.RunningJobs;
                    wa.ScopeExternalConnectionsToSiteSubscriptions = swa.ScopeExternalConnectionsToSiteSubscriptions;
                    wa.SecondStageRecycleBinQuota = swa.SecondStageRecycleBinQuota;
                    wa.SelfServiceCreateIndividualSite = swa.SelfServiceCreateIndividualSite;
                    wa.SelfServiceCreationParentSiteUrl = swa.SelfServiceCreationParentSiteUrl;
                    wa.SelfServiceCreationQuotaTemplate = swa.SelfServiceCreationQuotaTemplate;
                    wa.SelfServiceSiteCreationEnabled = swa.SelfServiceSiteCreationEnabled;
                    wa.SelfServiceSiteCustomFormUrl = swa.SelfServiceSiteCustomFormUrl;
                    wa.SendLoginCredentialsByEmail = swa.SendLoginCredentialsByEmail;
                    wa.SendSiteUpgradeEmails = swa.SendSiteUpgradeEmails;
                    wa.SendUnusedSiteCollectionNotifications = swa.SendUnusedSiteCollectionNotifications;
                    wa.ShowStartASiteMenuItem = swa.ShowStartASiteMenuItem;
                    wa.ShowURLStructure = swa.ShowURLStructure;
                    //wa.SiteDataServers = swa.SiteDataServers;
                    //wa.SiteSubscriptions = swa.SiteSubscriptions;
                    //wa.SiteUpgradeThrottleSettings = swa.SiteUpgradeThrottleSettings;
                    wa.StorageMetricsProcessingDuration = swa.StorageMetricsProcessingDuration;
                    wa.SuiteBarBrandingElementHtml = swa.SuiteBarBrandingElementHtml;
                    wa.SyndicationEnabled = swa.SyndicationEnabled;
                    wa.UnthrottledPrivilegedOperationWindowEnabled = swa.UnthrottledPrivilegedOperationWindowEnabled;
                    wa.UnusedSiteNotificationPeriod = swa.UnusedSiteNotificationPeriod;
                    wa.UnusedSiteNotificationsBeforeDeletion = swa.UnusedSiteNotificationsBeforeDeletion;
                    //wa.UpgradeContext = swa.UpgradeContext;
                    wa.UpgradeEvalSitesRetentionDays = swa.UpgradeEvalSitesRetentionDays;
                    wa.UpgradeMaintenanceLink = swa.UpgradeMaintenanceLink;
                    wa.UpgradeReminderDelay = swa.UpgradeReminderDelay;
                    wa.UseClaimsAuthentication = swa.UseClaimsAuthentication;
                    wa.UseExternalUrlZoneForAlerts = swa.UseExternalUrlZoneForAlerts;
                    wa.UseIncomingUriToValidateAudience = swa.UseIncomingUriToValidateAudience;
                    wa.UserDefinedWorkflowMaximumComplexity = swa.UserDefinedWorkflowMaximumComplexity;
                    wa.UserDefinedWorkflowsEnabled = swa.UserDefinedWorkflowsEnabled;
                    wa.UserPhotoErrorExpiration = swa.UserPhotoErrorExpiration;
                    wa.UserPhotoExpiration = swa.UserPhotoExpiration;
                    wa.UserPhotoImportEnabled = swa.UserPhotoImportEnabled;
                    wa.UserPhotoOnlineImportEnabled = swa.UserPhotoOnlineImportEnabled;
                    //wa.UserSettingsProvider = swa.UserSettingsProvider;
                    wa.Version = swa.Version;
                    //wa.WebConfigModifications = swa.WebConfigModifications;
                    wa.WebFileExtensions = swa.WebFileExtensions.ToArray<string>();
                    //wa.WebService = swa.WebService;
                    wa.ContentDBS = FillContentDatabase(swa.ContentDatabases);

                    wa.SiteCols = FillSite(swa.Sites);
                    lstWebApps.Add(wa);
                    _lstWebApps.Add(wa);
                }
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement des Web App", ex);
            }
            return lstWebApps.ToArray();
        }

        private string GetApplicationPoolPassword(string appPoolName)
        {
            try
            {
                OnFarmEvent("Get App Pool Password");
                ManagementScope scope = new ManagementScope("\\\\.\\ROOT\\MicrosoftIISv2");
                scope.Connect();
                ObjectQuery query = new ObjectQuery(string.Format("SELECT * FROM IIsApplicationPoolSetting where name=\"W3SVC/APPPOOLS/{0}\"", appPoolName));
                ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
                ManagementObjectCollection queryCollection = searcher.Get();
                foreach (ManagementObject obj in queryCollection)
                {
                    return obj["WAMUserPass"].ToString();
                }
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement des ApplicationPoolPassword", ex);
            }
            return "";
        }

        private SiteCollection[] FillSite(SPSiteCollection sc)
        {
            List<SiteCollection> lstSiteCol = new List<SiteCollection>();
            try
            {
                OnFarmEvent("Fill Site Collection");
                foreach (SPSite spsite in sc)
                {
                    SiteCollection sitecol = new SiteCollection();
                    sitecol.SiteCollectionURL = spsite.Url;
                    sitecol.Owner = spsite.Owner.LoginName;
                    sitecol.AdministrationSiteType = spsite.AdministrationSiteType.ToString();
                    sitecol.AllowCreateDeclarativeWorkflow = spsite.AllowCreateDeclarativeWorkflow;
                    sitecol.AllowDesigner = spsite.AllowDesigner;
                    sitecol.AllowExternalEmbedding = spsite.AllowExternalEmbedding.ToString();
                    sitecol.AllowMasterPageEditing = spsite.AllowMasterPageEditing;
                    sitecol.AllowRevertFromTemplate = spsite.AllowRevertFromTemplate;
                    sitecol.AllowRssFeeds = spsite.AllowRssFeeds;
                    sitecol.AllowSaveDeclarativeWorkflowAsTemplate = spsite.AllowSaveDeclarativeWorkflowAsTemplate;
                    sitecol.AllowSavePublishDeclarativeWorkflow = spsite.AllowSavePublishDeclarativeWorkflow;
                    sitecol.AllowSelfServiceUpgrade = spsite.AllowSelfServiceUpgrade;
                    sitecol.AllowSelfServiceUpgradeEvaluation = spsite.AllowSelfServiceUpgradeEvaluation;
                    sitecol.AllowUnsafeUpdates = spsite.AllowUnsafeUpdates;
                    sitecol.Archived = spsite.Archived;
                    sitecol.AverageResourceUsage = spsite.AverageResourceUsage;
                    sitecol.BrowserDocumentsEnabled = spsite.BrowserDocumentsEnabled;
                    sitecol.CatchAccessDeniedException = spsite.CatchAccessDeniedException;
                    sitecol.CertificationDate = spsite.CertificationDate;
                    sitecol.CompatibilityLevel = spsite.CompatibilityLevel;
                    sitecol.ContentDatabase = spsite.ContentDatabase.DisplayName;
                    sitecol.FeatureDefinitions = FillFeatureDefinitions(spsite.FeatureDefinitions);
                    sitecol.Features = FillFeature(spsite.Features);
                    sitecol.FileNotFoundUrl = spsite.FileNotFoundUrl;
                    sitecol.HideSystemStatusBar = spsite.HideSystemStatusBar;
                    sitecol.HostHeaderIsSiteName = spsite.HostHeaderIsSiteName;
                    sitecol.HostName = spsite.HostName;
                    sitecol.IISAllowsAnonymous = spsite.IISAllowsAnonymous;
                    sitecol.LastContentModifiedDate = spsite.LastContentModifiedDate;
                    sitecol.LastSecurityModifiedDate = spsite.LastSecurityModifiedDate;
                    sitecol.LockIssue = spsite.LockIssue;
                    sitecol.MaintenanceMode = spsite.MaintenanceMode;
                    sitecol.OutgoingEmailAddress = spsite.OutgoingEmailAddress;
                    sitecol.Owner = spsite.Owner.LoginName;
                    sitecol.Port = spsite.Port;
                    sitecol.PortalName = spsite.PortalName;
                    sitecol.PortalUrl = spsite.PortalUrl;
                    sitecol.Protocol = spsite.Protocol;
                    sitecol.ReadLocked = spsite.ReadLocked;
                    sitecol.ReadOnly = spsite.ReadOnly;
                    sitecol.RecycleBinItems = spsite.RecycleBin.Count;
                    sitecol.RequiredDesignerVersion = spsite.RequiredDesignerVersion;
                    sitecol.ResourceQuotaExceeded = spsite.ResourceQuotaExceeded;
                    sitecol.ResourceQuotaExceededNotificationSent = spsite.ResourceQuotaExceededNotificationSent;
                    sitecol.ResourceQuotaWarningNotificationSent = spsite.ResourceQuotaWarningNotificationSent;
                    sitecol.SchemaVersion = spsite.SchemaVersion.Major + "." + spsite.SchemaVersion.Minor + "." + spsite.SchemaVersion.Revision + "." + spsite.SchemaVersion.Build;
                    sitecol.SecondaryContact = spsite.SecondaryContact == null ? " " : spsite.SecondaryContact.LoginName;
                    sitecol.ShareByEmailEnabled = spsite.ShareByEmailEnabled;
                    sitecol.ShareByLinkEnabled = spsite.ShareByLinkEnabled;
                    sitecol.ShowURLStructure = spsite.ShowURLStructure;
                    sitecol.SyndicationEnabled = spsite.SyndicationEnabled;
                    sitecol.SystemAccount = spsite.SystemAccount.LoginName;
                    sitecol.Url = spsite.Url;
                    sitecol.UserCodeEnabled = spsite.UserCodeEnabled;
                    sitecol.UserDefinedWorkflowsEnabled = spsite.UserDefinedWorkflowsEnabled;
                    sitecol.WriteLocked = spsite.WriteLocked;
                    SPContentDatabase scd = spsite.ContentDatabase;
                    ContentDatabase cd = new ContentDatabase();
                    cd.CurrentSiteCount = scd.CurrentSiteCount;
                    cd.ConnectionString = scd.DatabaseConnectionString;
                    cd.DiskSpaceRequired = scd.DiskSizeRequired;
                    cd.DisplayName = scd.DisplayName;
                    cd.MaximumSiteCount = scd.MaximumSiteCount;
                    cd.NeedUpgrade = scd.NeedsUpgrade;
                    cd.NeedUpgradeIncludeChildren = scd.NeedsUpgradeIncludeChildren;
                    cd.AvailabilityGroup = scd.AvailabilityGroup == null ? "" : scd.AvailabilityGroup.DisplayName;
                    cd.BackupLocation = scd.BackupLocation;
                    cd.FailoverServerAddress = scd.FailoverServer == null ? "" : scd.FailoverServer.Address;
                    cd.IsSqlAzure = scd.IsSqlAzure;
                    cd.RemoteBlobStorageSettingsEnabled = scd.RemoteBlobStorageSettings.Enabled;
                    cd.MinimumBlobStorageSize = scd.RemoteBlobStorageSettings.MinimumBlobStorageSize;
                    cd.WarningSiteCount = scd.WarningSiteCount;

                    sitecol.ContentDataBase = cd;




                    sitecol.Sites = FillWeb(spsite.AllWebs);
                    lstSiteCol.Add(sitecol);
                }
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement des Site Collection", ex);
            }
            return lstSiteCol.ToArray();
        }

        private Site[] FillWeb(SPWebCollection wc)
        {
            List<Site> lstSite = new List<Site>();
            try
            {
               
                foreach (SPWeb web in wc)
                {
                    
                    Site site = new Site();
                    site.Features = FillFeature(web.Features);
                    site.Name = web.Name;
                    site.SiteURL = web.Url;
                    site.NoCrawl = web.NoCrawl;
                    site.Title = web.Title;
                    site.Description = web.Description;
                    site.AllowAnonymousAccess = web.AllowAnonymousAccess;
                    site.AllowAutomaticASPXPageIndexing = web.AllowAutomaticASPXPageIndexing;
                    site.AllowCreateDeclarativeWorkflowForCurrentUser = web.AllowCreateDeclarativeWorkflowForCurrentUser;
                    site.AllowDesignerForCurrentUser = web.AllowDesignerForCurrentUser;
                    site.AllowMasterPageEditingForCurrentUser = web.AllowMasterPageEditingForCurrentUser;
                    site.AllowRevertFromTemplateForCurrentUser = web.AllowRevertFromTemplateForCurrentUser;
                    site.AllowRssFeeds = web.AllowRssFeeds;
                    site.AllowSaveDeclarativeWorkflowAsTemplateForCurrentUser = web.AllowSaveDeclarativeWorkflowAsTemplateForCurrentUser;
                    site.AllowSavePublishDeclarativeWorkflowForCurrentUser = web.AllowSavePublishDeclarativeWorkflowForCurrentUser;
                    site.AllowUnsafeUpdates = web.AllowUnsafeUpdates;
                    site.Lists = FillList(web.Lists);
                    //site.ContentTypes=FillContentType( web.ContentTypes);
                    //site.Fields = FillFields(web.Fields);
                    //site.Alerts = FillAlert(web.Alerts);
                    //site.AllUsers = FillUser(web.AllUsers);
                    //site.AssociatedGroups =FillAssociateGroup( web.AssociatedGroups);
                    //site.ListTemplates = FillListTemplate(web.ListTemplates);
                    //site.RoleAssignments =FillRoleAssigment( web.RoleAssignments);
                    //site.RoleDefinitions = FillRoleDefinition(web.RoleDefinitions);
                    //site.RootFolder = web.RootFolder.Url;
                    //site.Webs = FillWeb(web.Webs);
                    //site.WebTemplates = FillWebTemplate(web.WebTemplate);
                    //site.Workflows = FillWorkflow(web.Workflows);
                    site.WorkflowTemplates = FillWorkflowTemplates(web.WorkflowTemplates);
                    site.IsWopiEnabled = IsWopiEnabled(web);
                    lstSite.Add(site);
                }
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement des Site", ex);
            }
            return lstSite.ToArray();
        }

        private SharePointDocumentor.SPModel.WorkflowTemplate[] FillWorkflowTemplates(Microsoft.SharePoint.Workflow.SPWorkflowTemplateCollection sPWorkflowTemplateCollection)
        {
            List<WorkflowTemplate> lstReturn = new List<WorkflowTemplate>();
            foreach (SPWorkflowTemplate tmpl in sPWorkflowTemplateCollection)
            {
                WorkflowTemplate wt = new WorkflowTemplate();
                wt.AllowManual=tmpl.AllowManual;
                wt.AssociationData = tmpl.AssociationData;
                wt.AssociationUrl = tmpl.AssociationUrl;
                wt.AutoStartChange = tmpl.AutoStartChange;
                wt.AutoStartCreate = tmpl.AutoStartCreate;
                wt.Description = tmpl.Description;
                wt.InstantiationUrl = tmpl.InstantiationUrl;
                wt.IsDeclarative = tmpl.IsDeclarative;
                wt.ModificationUrl = tmpl.ModificationUrl;
                wt.Name = tmpl.Name;
                wt.StatusColumn = tmpl.StatusColumn;
                wt.StatusUrl = tmpl.StatusUrl;
                wt.Xml = tmpl.Xml;
                lstReturn.Add(wt);

            }
            return lstReturn.ToArray();
        }

        private SharePointDocumentor.SPModel.Workflow[] FillWorkflow(Microsoft.SharePoint.Workflow.SPWorkflowCollection sPWorkflowCollection)
        {
            throw new NotImplementedException();
        }

        private SharePointDocumentor.SPModel.WebTemplate[] FillWebTemplate(string p)
        {
            throw new NotImplementedException();
        }

        private SharePointDocumentor.SPModel.RoleDefinition[] FillRoleDefinition(SPRoleDefinitionCollection sPRoleDefinitionCollection)
        {
            throw new NotImplementedException();
        }

        private SharePointDocumentor.SPModel.RoleAssignment[] FillRoleAssigment(SPRoleAssignmentCollection sPRoleAssignmentCollection)
        {
            throw new NotImplementedException();
        }

        private SharePointDocumentor.SPModel.ListTemplate[] FillListTemplate(SPListTemplateCollection sPListTemplateCollection)
        {
            throw new NotImplementedException();
        }

        private SharePointDocumentor.SPModel.Group[] FillAssociateGroup(IList<SPGroup> list)
        {
            throw new NotImplementedException();
        }

        private SharePointDocumentor.SPModel.User[] FillUser(SPUserCollection sPUserCollection)
        {
            throw new NotImplementedException();
        }

        private SharePointDocumentor.SPModel.Alert[] FillAlert(SPAlertCollection sPAlertCollection)
        {
            throw new NotImplementedException();
        }

        private SharePointDocumentor.SPModel.Field[] FillFields(SPFieldCollection sPFieldCollection)
        {
            throw new NotImplementedException();
        }

        private SharePointDocumentor.SPModel.ContentType[] FillContentType(SPContentTypeCollection sPContentTypeCollection)
        {
            throw new NotImplementedException();
        }

        private SharePointDocumentor.SPModel.SPDList[] FillList(SPListCollection sPListCollection)
        {
            List<SPDList> lstReturn = new List<SPDList>();
            foreach (SPList lst in sPListCollection)
            {
                SPDList spdlst = new SPDList();
                spdlst.AllowContentTypes = lst.AllowContentTypes;
                spdlst.AllowDeletion = lst.AllowDeletion;
                spdlst.AllowEveryoneViewItems = lst.AllowEveryoneViewItems;
                spdlst.AllowMultiResponses = lst.AllowMultiResponses;
                spdlst.AllowRssFeeds = lst.AllowRssFeeds;
                spdlst.Author = lst.Author.Name;
                spdlst.BaseTemplate = lst.BaseTemplate.ToString();
                spdlst.BaseType = lst.BaseType.ToString();
                spdlst.CanReceiveEmail = lst.CanReceiveEmail;
                spdlst.ContentTypesEnabled = lst.ContentTypesEnabled;
                spdlst.Created = lst.Created;
                spdlst.DefaultDisplayFormUrl = lst.DefaultDisplayFormUrl;
                spdlst.DefaultEditFormUrl = lst.DefaultEditFormUrl;
                spdlst.DefaultItemOpen = lst.DefaultItemOpen.ToString();
                spdlst.DefaultNewFormUrl = lst.DefaultNewFormUrl;
                spdlst.DefaultViewUrl = lst.DefaultViewUrl;
                spdlst.Description = lst.Description;
                spdlst.DisableGridEditing = lst.DisableGridEditing;
                spdlst.DraftVersionVisibility = lst.DraftVersionVisibility.ToString();
                spdlst.EmailAlias = lst.EmailAlias;
                spdlst.EnableAssignToEmail = lst.EnableAssignToEmail;
                spdlst.EnableAttachments = lst.EnableAttachments;
                spdlst.EnableFolderCreation = lst.EnableFolderCreation;
                spdlst.EnableMinorVersions = lst.EnableMinorVersions;
                spdlst.EnableModeration = lst.EnableModeration;
                spdlst.EnablePeopleSelector = lst.EnablePeopleSelector;
                spdlst.EnableSyndication = lst.EnableSyndication;
                spdlst.EnableThrottling = lst.EnableThrottling;
                spdlst.EnableVersioning = lst.EnableVersioning;
                spdlst.EnforceDataValidation = lst.EnforceDataValidation;
                spdlst.ExcludeFromOfflineClient = lst.ExcludeFromOfflineClient;
                spdlst.ForceCheckout = lst.ForceCheckout;
                spdlst.ForceDefaultContentType = lst.ForceDefaultContentType;
                spdlst.Hidden = lst.Hidden;
                spdlst.ID = lst.ID;
                spdlst.ImageUrl = lst.ImageUrl;
                spdlst.IrmEnabled = lst.IrmEnabled;
                spdlst.IrmExpire = lst.IrmExpire;
                spdlst.IrmReject = lst.IrmReject;
                spdlst.IsApplicationList = lst.IsApplicationList;
                spdlst.IsPrivate = lst.IsPrivate;
                spdlst.IsSiteAssetsLibrary = lst.IsSiteAssetsLibrary;
                spdlst.ItemCount = lst.ItemCount;
                spdlst.MajorVersionLimit = lst.MajorVersionLimit;
                spdlst.MajorWithMinorVersionsLimit = lst.MajorWithMinorVersionsLimit;
                spdlst.MobileDefaultDisplayFormUrl = lst.MobileDefaultDisplayFormUrl;
                spdlst.MobileDefaultEditFormUrl = lst.MobileDefaultEditFormUrl;
                spdlst.MobileDefaultNewFormUrl = lst.MobileDefaultNewFormUrl;
                spdlst.MobileDefaultViewUrl = lst.MobileDefaultViewUrl;
                spdlst.NavigateForFormsPages = lst.NavigateForFormsPages;
                spdlst.NoCrawl = lst.NoCrawl;
                spdlst.OnQuickLaunch = lst.OnQuickLaunch;
                spdlst.Ordered = lst.Ordered;
                spdlst.RootFolder = lst.RootFolder.Url;
                spdlst.SendToLocationName = lst.SendToLocationName;
                spdlst.SendToLocationUrl = lst.SendToLocationUrl;
                spdlst.Title = lst.Title;
                spdlst.UseFormsForDisplay = lst.UseFormsForDisplay;
                lstReturn.Add(spdlst);

            }
            return lstReturn.ToArray();
        }

        

        private ContentDatabase[] FillContentDatabase(SPContentDatabaseCollection cdc)
        {
            List<ContentDatabase> lstCD = new List<ContentDatabase>();
            try
            {
                OnFarmEvent("Fill Content Database");
                foreach (SPContentDatabase scd in cdc)
                {
                    
                    ContentDatabase cd = new ContentDatabase();
                    cd.CurrentSiteCount = scd.CurrentSiteCount;
                    cd.ConnectionString = scd.DatabaseConnectionString;
                    cd.DiskSpaceRequired = scd.DiskSizeRequired;
                    cd.DisplayName = scd.DisplayName;
                    cd.MaximumSiteCount = scd.MaximumSiteCount;
                    cd.NeedUpgrade = scd.NeedsUpgrade;
                    cd.NeedUpgradeIncludeChildren = scd.NeedsUpgradeIncludeChildren;
                    cd.AvailabilityGroup = scd.AvailabilityGroup == null ? "" : scd.AvailabilityGroup.DisplayName;
                    cd.BackupLocation = scd.BackupLocation;
                    cd.FailoverServerAddress = scd.FailoverServer == null ? "" : scd.FailoverServer.Address;
                    cd.IsSqlAzure = scd.IsSqlAzure;
                    cd.RemoteBlobStorageSettingsEnabled = scd.RemoteBlobStorageSettings.Enabled;
                    cd.MinimumBlobStorageSize = scd.RemoteBlobStorageSettings.MinimumBlobStorageSize;
                    cd.WarningSiteCount = scd.WarningSiteCount;

                    lstCD.Add(cd);
                    
                }
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement des Content DB", ex);
            }
            return lstCD.ToArray();
        }

        private FileMimeMapping[] FillMimeMappings(SPMimeMappingCollection sPMimeMappingCollection)
        {
            OnFarmEvent("Fill Mime Mapping");

            List<FileMimeMapping> lstMimeMapping = new List<FileMimeMapping>();
            try
            {
                foreach (SPMimeMapping mm in sPMimeMappingCollection)
                {
                    FileMimeMapping m = new FileMimeMapping();
                    m.Extension = mm.Extension;
                    m.MimeType = mm.MimeType;
                    m.ProgId = mm.ProgId;
                    lstMimeMapping.Add(m);
                }
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement des Mime Type", ex);
            }
            return lstMimeMapping.ToArray();
        }

        private static ZoneIISSettings FillIisSettings(IisSettings iisSetting, KeyValuePair<SPUrlZone, SPIisSettings> iis)
        {
            OnFarmEvent("Fill IIS Settings");

            ZoneIISSettings zis = new ZoneIISSettings();
            try
            {
                zis.AllowAnonymous = iis.Value.AllowAnonymous;
                if (iis.Value.AuthenticationMode == System.Web.Configuration.AuthenticationMode.Forms)
                    zis.AuthenticationMode = "Forms";
                else if (iis.Value.AuthenticationMode == System.Web.Configuration.AuthenticationMode.None)
                    zis.AuthenticationMode = "None";
                else if (iis.Value.AuthenticationMode == System.Web.Configuration.AuthenticationMode.Windows)
                    zis.AuthenticationMode = "Windows";
                zis.DisableKerberos = iis.Value.DisableKerberos;
                zis.EnableClientIntegration = iis.Value.EnableClientIntegration;
                zis.OnlyUseWindowsClaimsAuthenticationProvider = iis.Value.OnlyUseWindowsClaimsAuthenticationProvider;
                zis.Path = iis.Value.Path.FullName;
                zis.UseBasicAuthentication = iis.Value.UseBasicAuthentication;
                zis.UseClaimsAuthentication = iis.Value.UseClaimsAuthentication;
                zis.UseFormsClaimsAuthenticationProvider = iis.Value.UseFormsClaimsAuthenticationProvider;
                zis.UseTrustedClaimsAuthenticationProvider = iis.Value.UseTrustedClaimsAuthenticationProvider;
                zis.UseWindowsClaimsAuthenticationProvider = iis.Value.UseWindowsClaimsAuthenticationProvider;
                zis.UseWindowsIntegratedAuthentication = iis.Value.UseWindowsIntegratedAuthentication;
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement des IIS Settings", ex);
            }
            return zis;
        }

        private Feature[] FillFeature(SPFeatureCollection SPFeatures)
        {
            List<FeatureDefinition> lstFeatureDef = new List<FeatureDefinition>();
            lstFeatureDef.AddRange(FillFeatureDefinitions(SPFarm.Local.FeatureDefinitions));
            List<Feature> lstFeature = new List<Feature>();
            try
            {

                foreach (SPFeature feature in SPFeatures)
                {
                    //OnFarmEvent("Fill Feature");

                    Feature f = new Feature();
                    f.FeatureID = feature.DefinitionId;
                    f.Scope = feature.FeatureDefinitionScope;
                    f.Activated = feature.TimeActivated;
                    if (feature.Definition != null)
                    {
                        f.FeatureName = feature.Definition.DisplayName;

                        f.FeatureDefinition = FillFeatureDefinition(feature.Definition);
                    }
                    else
                    {

                        var fe = (from fc in lstFeatureDef where fc.FeatureID == feature.DefinitionId select fc).FirstOrDefault();
                        if (fe != null)
                            f.FeatureDefinition = fe;
                    }

                    f.Version = feature.Version.ToString();

                    lstFeature.Add(f);
                }
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement des Feature", ex);
            }
            return lstFeature.ToArray();
        }

        private AlternateUrl FillAlternateUrl(SPAlternateUrlCollection AlternateUrls)
        {
            OnFarmEvent("Fill AAM");

            AlternateUrl aurl = new AlternateUrl();
            try
            {
                aurl.DisplayName = AlternateUrls.DisplayName;
                foreach (SPAlternateUrl url in AlternateUrls)
                {
                    switch (url.UrlZone)
                    {
                        case SPUrlZone.Default:
                            aurl.DefaultZoneURL = url.IncomingUrl;
                            break;
                        case SPUrlZone.Extranet:
                            aurl.ExtranetZoneURL = url.IncomingUrl;
                            break;
                        case SPUrlZone.Internet:
                            aurl.InternetZoneURL = url.IncomingUrl;
                            break;
                        case SPUrlZone.Intranet:
                            aurl.IntranetZoneURL = url.IncomingUrl;
                            break;
                        case SPUrlZone.Custom:
                            aurl.CustomZoneURL = url.IncomingUrl;
                            break;

                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement des AAM", ex);
            }
            return aurl;
        }

        private Server[] FillServers(SPServerCollection ssc)
        {
            if (lstServ != null)
                return lstServ.ToArray();
            lstServ = new List<Server>();
            try
            {
                foreach (SPServer s in ssc)
                {
                    OnFarmEvent("Fill Server");

                    Server srv = new Server();
                    srv.ServerName = s.DisplayName;
                    srv.Role = s.Role.ToString();
                    srv.OperatingSystem = GetOS(s.Address);
                    srv.Memory = GetMemory(s.Address);
                    srv.Drives = GetSpace(s.Address);
                    srv.Patches = getPatches(s.Address);
                    srv.Services = FillServices(s.ServiceInstances);
                    lstServ.Add(srv);
                }
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement des Server", ex);
            }
            return lstServ.ToArray();
        }

        private Service[] FillServices(SPServiceInstanceCollection SPServiceInstances)
        {
            List<Service> lstReturn = new List<Service>();
            try
            {
                foreach (SPServiceInstance si in SPServiceInstances)
                {
                    Service srv = new Service();
                    srv.DisplayName = si.DisplayName;
                    srv.Description = si.Description;
                    srv.Hidden = si.Hidden;
                    srv.ServiceID = si.Id;
                    srv.Instance = si.Instance;
                    srv.Name = si.TypeName;
                    srv.JobDefinitions = FillJobDefinitions(si.Service.JobDefinitions);
                    srv.ServiceApplications = FillServiceApplication(si.Service.Applications);
                    lstReturn.Add(srv);
                }
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement des Services", ex);
            }
            return lstReturn.ToArray();
        }

        private Drive[] GetSpace(string ServerName)
        {
            OnFarmEvent("Fill Drive Data");

            List<Drive> lstDrive = new List<Drive>();
            try
            {
                ManagementScope scope = new ManagementScope(string.Format("\\\\{0}\\root\\cimv2", ServerName));
                scope.Connect();
                ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_Volume");
                ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
                ManagementObjectCollection queryCollection = searcher.Get();

                foreach (ManagementObject obj in queryCollection)
                {
                    Drive drv = new Drive();
                    drv.TotalSpace = obj["Capacity"] == null ? "" : obj["Capacity"].ToString();
                    drv.FreeSpace = obj["FreeSpace"] == null ? "" : obj["FreeSpace"].ToString();
                    drv.Label = obj["Label"] == null ? "" : obj["Label"].ToString();
                    drv.Letter = obj["DriveLetter"] == null ? "" : obj["DriveLetter"].ToString();
                    lstDrive.Add(drv);
                }
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement des Lecteurs", ex);
            }
            return lstDrive.ToArray();
        }

        private double GetMemory(string ServerName)
        {
            OnFarmEvent("Fill Memory Data");

            try
            {
                ManagementScope scope = new ManagementScope(string.Format("\\\\{0}\\root\\cimv2", ServerName));
                scope.Connect();
                ObjectQuery query = new ObjectQuery("SELECT TotalPhysicalMemory FROM Win32_ComputerSystem");
                ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
                ManagementObjectCollection queryCollection = searcher.Get();
                foreach (ManagementObject obj in queryCollection)
                {
                    return (Convert.ToDouble(obj["TotalPhysicalMemory"]) / 1024 / 1024 / 1024);
                }
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement de la mémoire", ex);
            }
            return 0;
        }

        private ServerPatche[] getPatches(string ServerName)
        {
            OnFarmEvent("Fill Patch");

            List<ServerPatche> lstReturn = new List<ServerPatche>();
            try
            {
                ManagementScope scope = new ManagementScope(string.Format("\\\\{0}\\root\\cimv2", ServerName));
                scope.Connect();
                ObjectQuery query = new ObjectQuery("SELECT * FROM win32_quickfixengineering");
                ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
                ManagementObjectCollection queryCollection = searcher.Get();
                foreach (ManagementObject obj in queryCollection)
                {
                    ServerPatche sp = new ServerPatche();
                    sp.HotfixID = obj["HotfixID"] == null ? "" : obj["HotfixID"].ToString();
                    sp.ServicePackInEffect = obj["ServicePackInEffect"] == null ? "" : obj["ServicePackInEffect"].ToString();
                    sp.InstallDate = obj["InstallDate"] == null ? "" : obj["InstallDate"].ToString();
                    sp.InstalledBy = obj["InstalledBy"] == null ? "" : obj["InstalledBy"].ToString();
                    sp.InstalledOn = obj["InstalledOn"] == null ? "" : obj["InstalledOn"].ToString();
                    sp.Caption = obj["Caption"] == null ? "" : obj["Caption"].ToString();
                    sp.Description = obj["Description"] == null ? "" : obj["Description"].ToString();
                    sp.Status = obj["Status"] == null ? "" : obj["Status"].ToString();
                    lstReturn.Add(sp);
                }
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement de la mémoire", ex);
            }
            return lstReturn.ToArray();

        }


        private string GetOS(string ServerName)
        {
            OnFarmEvent("Fill OS Values");

            try
            {
                ManagementScope scope = new ManagementScope(string.Format("\\\\{0}\\root\\cimv2", ServerName));
                scope.Connect();
                ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_OperatingSystem");
                ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
                ManagementObjectCollection queryCollection = searcher.Get();
                foreach (ManagementObject obj in queryCollection)
                {
                    return obj["Caption"].ToString();
                }
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement de l'os", ex);
            }
            return "";


        }
        private string[] GetSharePointEdition()
        {
            OnFarmEvent("Fill SharePoint Edition");

            List<string> lstReturn = new List<string>();
            try
            {
                using (RegistryKey key = Registry.LocalMachine.OpenSubKey(SharePointProductsRegistryPath, false))
                {
                    //Get all of the installed product code/SKUId pairs.
                    foreach (String value in key.GetValueNames())
                    {
                        try
                        {
                            //Get the SKUId and see whether it is a known product.
                            String SKUId = key.GetValue(value) as String;

                            if (SharePointProducts[SKUId] != null)
                            {
                                lstReturn.Add(SharePointProducts[SKUId].ToString());
                            }
                            else
                            {
                                lstReturn.Add(String.Format("Unknown Product: {0}", SKUId));
                            }
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("Could not read key exception was {0}", e.Message);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement de la version de SP", ex);
            }
            return lstReturn.ToArray();
        }
        public bool IsWopiEnabled(SPWeb web)
        {
            try
            {
                Assembly spAssembly = Assembly.Load("Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c");
                Type Wopi = spAssembly.GetType("Microsoft.SharePoint.Utilities.SPWOPIHost");
                var method = Wopi.GetMethod("IsWOPIEnabled", BindingFlags.Static | BindingFlags.NonPublic, null, new Type[] { typeof(SPWeb) }, null);
                object o = method.Invoke(null, new object[] { web });
                return (bool)o;
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement de la version de WOPI", ex);
            }
            return false;
        }

        public string GetConfigDbConnectionString(SPFarm LocalFarm)
        {
            OnFarmEvent("Fill Config DB");

            try
            {
                var version = LocalFarm.BuildVersion.Major.ToString() + "." + LocalFarm.BuildVersion.Minor.ToString();
                var configDbKey = Registry.LocalMachine.OpenSubKey(string.Format(@"SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\{0}\Secure\ConfigDB", version));
                if (configDbKey != null)
                {
                    var connString = configDbKey.GetValue("dsn").ToString();
                    return connString;
                }
            }
            catch (Exception ex)
            {
                Log.Error("Erreur dans le chargement de la version de la chaine de connection", ex);
            }
            return string.Empty;
        }
    }
}
